package be.nvlooy.moviereminder.service.implementations;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import be.nvlooy.moviereminder.common.ImageResizer;
import be.nvlooy.moviereminder.dto.MovieDTO;
import be.nvlooy.moviereminder.entities.Movie;
import be.nvlooy.moviereminder.service.BasicService;
import be.nvlooy.moviereminder.service.MovieService;

@Service
@Scope("singleton")
public class MovieServiceImpl extends BasicService implements MovieService {
	
	private EntityManager em;
	
	@Autowired
	public void setEntityManager(EntityManager em) {
		this.em = em;
	}

	@Override
	public Movie getMovieByID(int movieID) {
		return em.find(Movie.class, (long) movieID);
	}

	@Override
	public Movie getByTypeAndSourceId(Movie movie) {
		Query query = em.createNamedQuery("Movie.getByTypeAndSourceId");
		query.setParameter("sourceId", movie.getId());
		query.setParameter("sourceType", movie.getOriginalSourceType());
		
		try {
			movie = (Movie) query.getSingleResult();
		}
		catch(javax.persistence.NoResultException ex) {}
		
		return movie;
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public Movie addMovieFromDTO(MovieDTO movieDto) {
		// if it does exist then return the persistent entity
		Movie movie = getMoviePojoFromDTO(movieDto);
		Movie existingMovie = 
			getByTypeAndSourceId(movie);
		
		// check if the movie already exists in the database, if not then add it
		if(existingMovie != null) {
			return existingMovie;
		}
		else {
			em.persist(movie);
			return movie;
		}
	}
	
	public Movie getMoviePojoFromDTO(MovieDTO movieDto) {
		Movie movie = new Movie();
		
		// create a Movie object from the tmdb Movie object
		movie.setTitle(movieDto.getName());
		movie.setOriginalSourceId(movieDto.getSourceId());
		movie.setOriginalSourceType(movieDto.getSourceType());
		movie.setReleaseDate(movieDto.getReleasedDate());
		movie.setOverview(movieDto.getOverview());
		movie.setLanguage(movieDto.getLanguage());
		movie.setRating(movieDto.getRating());
		
		if(movieDto.getCover() != null) {
			try {
				// resize cover to moviereminderformat
				BufferedImage target = ImageResizer.scaleFit((BufferedImage) movieDto.getCover(), 140, 224);
				ByteArrayOutputStream bas =	new ByteArrayOutputStream();
				ImageIO.write(target, "jpg", bas);
				movie.setCover(bas.toByteArray());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
			
		return movie;
	}

}
